﻿Public Class CommandManager
    Private Shared _instance As CommandManager
    Private _done As New List(Of CommandBase)
    Private _undone As New List(Of CommandBase)
    Public Event CssChanged(ByVal Sender As Object, ByVal E As CssChangedEventArgs)
    Public Event ImagingChanged(ByVal Sender As Object, ByVal e As ImagingChangedEventArgs)
    Private _atomiccommand As CompositeCommand
    Private _iscommandatomic As Boolean = False
    Private Sub New()

    End Sub
    Public Sub StartAtomicCommand()
        _iscommandatomic = True
        _atomiccommand = New CompositeCommand
    End Sub
    Public Sub EndAtomicCommand()
        _iscommandatomic = False
        If _atomiccommand IsNot Nothing Then
            ExecuteCommand(_atomiccommand)
        End If
    End Sub
    Public Shared ReadOnly Property Instance As CommandManager
        Get
            If _instance Is Nothing Then
                _instance = New CommandManager
            End If
            Return _instance
        End Get
    End Property
    Public Sub ExecuteCommand(ByVal Command As CommandBase)
        If _iscommandatomic Then
            _atomiccommand.Commands.Add(Command)
        Else
            AddHandler Command.CssChanged, AddressOf onCssChanged
            AddHandler Command.ImagingChanged, AddressOf onImagingChanged
            _done.Add(Command)
            If _done.Count > 20 Then
                _done.RemoveAt(0)
            End If
            _undone.Clear()
            Command.Execute()
        End If
    End Sub
    Public Sub Undo()
        If _done.Count > 0 Then
            Dim c As CommandBase = _done(_done.Count - 1)
            _done.Remove(c)
            _undone.Add(c)
            c.Undo()
        End If
    End Sub
    Public Sub Redo()
        If _undone.Count > 0 Then
            Dim c As CommandBase = _undone(_undone.Count - 1)
            _undone.Remove(c)
            _done.Add(c)
            c.Execute()
        End If
    End Sub
    Public Function CanUndo() As Boolean
        Return _done.Count > 0
    End Function
    Public Function CanRedo() As Boolean
        Return _undone.Count > 0
    End Function
    Protected Sub onCssChanged(ByVal Sender As Object, ByVal e As CssChangedEventArgs)
        RaiseEvent CssChanged(Sender, e)
    End Sub
    Protected Sub onImagingChanged(ByVal Sender As Object, ByVal e As ImagingChangedEventArgs)
        RaiseEvent ImagingChanged(Sender, e)
    End Sub
End Class